﻿using Sgr.Domain.Entities;
using Sgr.Domain.Managers;
using Sgr.Exceptions;
using System.Threading;
using System.Threading.Tasks;

namespace Sgr.UPMS.Domain.Menus
{
    /// <summary>
    /// 菜单管理接口
    /// </summary>
    public interface IMenuManage : ITreeNodeManage<Menu, long>
    {
        /// <summary>
        /// 创建菜单
        /// <para>规则1：同级菜单名称唯一性</para>
        /// <para>规则2：菜单层级不超过5级</para>
        /// <para>规则3：目录节点只能放置到目录节点下</para>
        /// <para>规则4：菜单节点只能放置到目录节点下</para>
        /// </summary>
        /// <param name="name">菜单名称</param>
        /// <param name="type">菜单类型</param>
        /// <param name="parentId">父级菜单ID</param>
        /// <param name="permission">权限标识</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>创建的菜单</returns>
        Task<Menu> CreateAsync(string name,
            MenuType type,
            long? parentId = null,
            string? permission = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 验证同级菜单名称是否唯一
        /// </summary>
        /// <param name="name">菜单名称</param>
        /// <param name="parentId">父级菜单ID</param>
        /// <param name="excludeId">需要排除的菜单ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <exception cref="DomainException">当名称重复时抛出异常</exception>
        Task<DomainRuleCheckResult> ValidateNameUniquenessAsync(string name,
            long parentId,
            long? excludeId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 验证路由名称是否唯一
        /// </summary>
        /// <param name="routeName"></param>
        /// <param name="excludeId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<DomainRuleCheckResult> ValidateRouteNameUniquenessAsync(string routeName,
            long? excludeId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 激活菜单及其子菜单
        /// </summary>
        /// <param name="menu">菜单</param>
        /// <param name="cancellationToken">取消令牌</param>
        Task ActivateAsync(Menu menu, CancellationToken cancellationToken = default);

        /// <summary>
        /// 停用菜单及其子菜单
        /// </summary>
        /// <param name="menu">菜单</param>
        /// <param name="cancellationToken">取消令牌</param>
        Task DeactivateAsync(Menu menu, CancellationToken cancellationToken = default);
    }
}